#pragma once

#include "Connection.h"
// #include "Util.hpp"
#include <functional>
#include <HttpRequest.h>
#include <HttpResponse.h>
#include <string>
#include <utility>
#include <TcpServer.h>

#define TIMEOUT 10

namespace muduo{
    // class Util;
    class HttpServer{
    private:
        using Handler = std::function<void(const HttpRequest&,HttpResponse*)>;          //路由表管理的匹配成功后的调用方法Handler
        using Handlers = std::vector<std::pair<std::regex, Handler>>;                   //路由表，当通过正则表达式匹配成功后执行的Handler
        Handlers _get_routine;       //GET请求方法调用函数
        Handlers _post_routine;      //POST请求方法调用函数
        Handlers _put_routine;       //PUT请求方法调用函数
        Handlers _delete_routine;    //DELETE请求方法调用函数
        std::string _base_dir;      //静态资源根路径
        TcpServer _server;          //服务器对象
    private:
        void Route(HttpRequest& request,HttpResponse *response);
        void ErrorHandler(HttpRequest& request,HttpResponse *response);
        void WriteResponse(const PtrConnection con,const HttpRequest& request,HttpResponse *response);
        bool IsFileHandler(const HttpRequest& request);
        void FileHandler(const HttpRequest& request,HttpResponse* response);
        void Dispatcher(HttpRequest& request,HttpResponse *response,const Handlers& handlers);
        void OnMessage(const PtrConnection con,Buffer* buffer);                   //解析+处理缓冲区中的内容
        void OnConnected(const PtrConnection con);
        public:
        HttpServer(int port,int timeout=TIMEOUT);                               
        void SetBaseDir(const std::string& basedir);                    //设置静态资源根路径
        void Get(const std::string& pattern,const Handler& handler);    //添加GET请求（正则表达式）与处理函数的映射
        void Post(const std::string& pattern,const Handler& handler);   //添加Post请求（正则表达式）与处理函数的映射
        void Put(const std::string& pattern,const Handler& handler);    //添加Put请求（正则表达式）与处理函数的映射
        void Delete(const std::string& pattern,const Handler& handler); //添加Delete请求（正则表达式）与处理函数的映射
        void SetThreatPoolNum(int num);     //设置线程池数量
        void Listen();                      //启动server
    };
}